﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;

using System.Data.SqlClient;
using System.Data;
using System.Threading;
using System.Collections;

using System.ComponentModel;


namespace XEvents.Library.Targets
{
    public class Target_File : TargetData
    {

        Dictionary<string, int> tablecols = new Dictionary<string, int>();

        #region Constructor

        private Target_File(SqlServer server, EventSessionTarget parent)
            : base(server, parent)
        {        }

        internal static TargetData GetTargetData(SqlServer server, EventSessionTarget parent)
        {            
            Target_File tf = new Target_File(server, parent);
            return tf;
        }

        #endregion

        #region TargetData Overrides

        protected override void InitalizeTarget()
        {
            targetinfo = InitializeTable();
            targetinfo.TableName = "EventInformation";

            string data = Parent.Parent.Server.ServerConnection.ExecuteScalar(string.Format(SqlCommandStrings.TargetData, Parent.parent.Name, Parent.Name.Split('.').ElementAt(1))).ToString();
            XDocument xdocument = XDocument.Parse(data);

            this.truncated = (int)xdocument.Element("FileTarget").Attribute("truncated");
            this.buffersdropped = (int)xdocument.Element("FileTarget").Element("Buffers").Attribute("logged");
            this.bufferslogged = (int)xdocument.Element("FileTarget").Element("Buffers").Attribute("dropped");
        }

        private DataTable InitializeTable()
        {
            tablecols = new Dictionary<string, int>();
            DataTable dt = new DataTable();
            dt.Columns.Add("Id");
            dt.Columns.Add("Name");
            dt.Columns.Add("Package");
            dt.Columns.Add("Version");
            dt.Columns.Add("TimeStamp");

            foreach (string s in DataColumns)
            {
                dt.Columns.Add(s);
            }

            foreach (DataColumn dc in dt.Columns)
                tablecols.Add(dc.ColumnName, dc.Ordinal);
            return dt;

        }
        protected override void LoadData()
        {
            //this.targetinfo = InitializeTable();

            ChangeStatus(LoadStatus.Requesting_Data);

            string cmd = string.Format(SqlCommandStrings.FileTargetData, FileName, MetaFileName);

            SqlConnection conn = new SqlConnection(Server.ServerConnection.ConnectionString);
            conn.Open();
            SqlCommand sqlcmd = new SqlCommand(cmd, conn);
            SqlDataReader dr = sqlcmd.ExecuteReader();

            int i = 0;

            targetinfo.BeginLoadData();

            while (dr.Read())
            {
                if (bw.CancellationPending)
                    break;

                //System.Diagnostics.Debug.WriteLine(i);

                ProcessRow(dr);
                if (i == 0)
                    TargetInfoChanged();

                i++;

                if (i % 50 == 0)
                {
                    bw.ReportProgress((int)((float)i / (float)1000 * 100));
                }
                if (i % 1000 == 0)
                {
                    System.Diagnostics.Debug.WriteLine(i);
                    i = 1;
                }
            }
            targetinfo.EndLoadData();

            //dr.Close();
            conn.Close();

            ChangeStatus(LoadStatus.Completed);
        }

        void ProcessRow(SqlDataReader dr)
        {
            targetinfo.LoadDataRow((from dc in tablecols
                                    join di in GetEventData(new fn_xe_file_target_read_file(dr)) on dc.Key.ToLower() equals di.Key.ToLower() into r
                                    from di in r.DefaultIfEmpty()
                                    orderby dc.Value
                                    select di.Value == null ? string.Empty : di.Value).ToArray(), true);
        }

        private Dictionary<string, string> GetEventData(fn_xe_file_target_read_file data)
        {
            return (
                        from fe in data.event_data.Elements()
                        from a in fe.Attributes()
                        select new { Name = a.Name.LocalName, a.Value }
                   )
            .Union
                   (
                        from fe in data.event_data.Elements()
                        from pc in fe.Descendants("data")
                        select new { Name = (string)pc.Attribute("name"), Value = ((string)pc.Element("text").Value == string.Empty ? (string)pc.Element("value").Value : (string)pc.Element("text").Value) }
                   )
            .ToDictionary(a => a.Name, a=> a.Value);
        }
        private string FileName
        {
            get
            {
                string file = Parent.Options["filename"].Value;
                return file.Substring(0, file.LastIndexOf(".")) + "*" + file.Substring(file.LastIndexOf("."));
            }
        }
        private string MetaFileName
        {
            get
            {
                string meta;
                if (Parent.Options.Where(p => p.Name == "metadatafile").Count() > 0)
                    meta = Parent.Options["metadatafile"].Value;
                else
                    meta = FileName.Substring(0, FileName.LastIndexOf(".")) + ".XEM";
                return meta.Substring(0, meta.LastIndexOf(".")) + "*" + meta.Substring(meta.LastIndexOf("."));
            }

        }

        #endregion

        #region Private Methods

        private List<string> DataColumns
        {
            get
            {
                return
                    (from s in Server.sessiondata.server_event_sessions
                     from e in Server.sessiondata.server_event_session_events
                     from p in Server.MetaData.packages
                     from c in Server.MetaData.object_columns
                     where s.name == this.Parent.Parent.name
                         && e.event_session_id == s.event_session_id
                         && p.name == e.package
                         && c.object_package_guid == p.guid
                         && c.object_name == e.name
                        && c.column_type != "readonly"
                     select c.name)
                     .Union
                     (from s in Server.sessiondata.server_event_sessions
                      from a in Server.sessiondata.server_event_session_actions
                      where s.name == this.Parent.Parent.name
                          && a.event_session_id == s.event_session_id
                      select a.name)
                      .Distinct()
                      .OrderBy(s => s)
                      .ToList();
            }
        }
        private List<string> GetFileList()
        {
            List<string> ret = new List<string>();
            SqlConnection conn = new SqlConnection(Server.ServerConnection.ConnectionString);

            conn.Open();
            SqlCommand sqlcmd = new SqlCommand(FileListCommand, conn);
            sqlcmd.Parameters.Add(new SqlParameter("@session_name", this.Parent.Parent.Name));

            SqlDataReader dr = sqlcmd.ExecuteReader();
            while (dr.Read())
            {
                ret.Add(dr.GetString(0));
            }
            return ret;
        }

        #endregion

        private string FileListCommand = @"
declare @filename varchar(1000)
select @filename = cast(f.value as varchar)
from sys.server_event_sessions s
join sys.server_event_session_targets t on s.event_session_id = t.event_session_id
join sys.server_event_session_fields f on t.event_session_id = f.event_session_id 
	and t.target_id = f.object_id
where s.name = @session_name 
  and t.name = 'asynchronous_file_target'
  and f.name = 'filename'

declare @Path nvarchar(255)
declare @Name nvarchar(255)

select @Path = LEFT(@filename, LEN(@filename)-CHARINDEX('\',REVERSE(@filename))+1)
create table #filetmp (Name nvarchar(255) NOT NULL, depth int NOT NULL, IsFile bit NULL ) 
insert #filetmp EXECUTE master.dbo.xp_dirtree @Path, 1, 1 

SELECT
@Path+Name AS [Name],
IsFile AS [IsFile]
FROM
#filetmp
WHERE right(Name, 3) like RIGHT(@filename, 3)
ORDER BY
[IsFile] ASC,[Name] ASC
drop table #filetmp";

        internal FiredEventCollection events = new FiredEventCollection();
        internal int truncated;
        internal int bufferslogged;
        internal int buffersdropped;
/*
<FileTarget truncated="0">
  <Buffers logged="0" dropped="0" />
</FileTarget>
*/

        public int Truncated
        {
            get { return truncated; }
        }

        public int BuffersLogged
        {
            get { return bufferslogged; }
        }

        public int BuffersDropped
        {
            get { return buffersdropped; }
        }


        public FiredEventCollection Events
        {
            get { return events; }
        }

        public System.Xml.XmlDocument GetEventXml()
        {
            return Utilities.GetSerializedXml(typeof(FiredEventCollection), this.Events);
        }


        #region Old Code

        private void ProcessEvent(object o)
        {

            DataRow row = targetinfo.NewRow();
            FiredEvent firedevent = (FiredEvent)o;

            row["Id"] = firedevent.Id;
            row["Name"] = firedevent.Name;
            row["Package"] = firedevent.Package;
            row["Version"] = firedevent.Version;
            row["TimeStamp"] = firedevent.Timestamp;
            foreach (EventPayloadItem epi in firedevent.EventPayloadItemCollection)
            {
                if (epi.Text == string.Empty)
                    row[epi.Name] = epi.Value;
                else
                    row[epi.Name] = epi.Text;
            }

            lock (locker)
                targetinfo.Rows.Add(row);
            targetinfo.AcceptChanges();
            //this.events.Add(firedevent);
        }

        private FiredEvent GetFiredEvent(fn_xe_file_target_read_file eventinfo)
        {
            return (
                from fe in eventinfo.event_data.Elements()
                select new FiredEvent
                {
                    name = (string)fe.Attribute("name"),
                    package = (string)fe.Attribute("package"),
                    id = (string)fe.Attribute("id"),
                    version = (string)fe.Attribute("version"),
                    timestamp = (string)fe.Attribute("timestamp"),
                    payloaddata = new EventPayloadItemCollection((
                        from pc in fe.Descendants("data")
                        select new EventPayloadItem(Server)
                        {
                            payloaditemtype = "Column",
                            name = (string)pc.Attribute("name"),
                            package = (string)pc.Attribute("package"),
                            //type_name = (string)pc.Element("type").Attribute("name"),
                            //type_package = (string)pc.Element("type").Attribute("package"),
                            value = (string)pc.Element("value").Value,
                            text = (string)pc.Element("text").Value
                        }).Union<EventPayloadItem>(
                        from pa in fe.Descendants("action")
                        select new EventPayloadItem(Server)
                        {
                            payloaditemtype = "Action",
                            name = (string)pa.Attribute("name"),
                            package = (string)pa.Attribute("package"),
                            //type_name = (string)pa.Element("type").Attribute("name"),
                            //type_package = (string)pa.Element("type").Attribute("package"),
                            value = (string)pa.Element("value").Value,
                            text = (string)pa.Element("text").Value
                        }))
                }).ElementAt(0);
        }

        protected void ResetData()
        {
            this.events = new FiredEventCollection();
            this.targetinfo = InitializeTable();
        }


        protected void LoadData_verygood()
        {
            this.targetinfo.Clear();

            ChangeStatus(LoadStatus.Requesting_Data);

            string cmd = string.Format(SqlCommandStrings.FileTargetData, FileName, MetaFileName);

            SqlConnection conn = new SqlConnection(Server.ServerConnection.ConnectionString);
            conn.Open();
            SqlCommand sqlcmd = new SqlCommand(cmd, conn);
            SqlDataReader dr = sqlcmd.ExecuteReader();

            List<fn_xe_file_target_read_file> rows = new List<fn_xe_file_target_read_file>();

            int i = 0;
            while (dr.Read())
            {
                if (bw.CancellationPending)
                    break;
                rows.Add(new fn_xe_file_target_read_file(dr));
                i++;

                if (i % 50 == 0)
                {
                    //bw.ReportProgress((int)((float)i / (float)1000 * 100));
                }
                if (i % 1000 == 0)
                {
                    i = 0;
                }
            }

            dr.Close();
            conn.Close();

            ChangeStatus(LoadStatus.Processing_Data);

            List<FiredEvent> events = (from r in rows
                                       from fe in r.event_data.Elements()
                                       select new FiredEvent
                                       {
                                           name = (string)fe.Attribute("name"),
                                           package = (string)fe.Attribute("package"),
                                           id = (string)fe.Attribute("id"),
                                           version = (string)fe.Attribute("version"),
                                           timestamp = (string)fe.Attribute("timestamp"),
                                           payloaddata = new EventPayloadItemCollection((
                                               from pc in fe.Descendants("data")
                                               select new EventPayloadItem(Server)
                                               {
                                                   payloaditemtype = "Column",
                                                   name = (string)pc.Attribute("name"),
                                                   package = (string)pc.Attribute("package"),
                                                   //type_name = (string)pc.Element("type").Attribute("name"),
                                                   //type_package = (string)pc.Element("type").Attribute("package"),
                                                   value = (string)pc.Element("value").Value,
                                                   text = (string)pc.Element("text").Value
                                               }).Union<EventPayloadItem>(
                                               from pa in fe.Descendants("action")
                                               select new EventPayloadItem(Server)
                                               {
                                                   payloaditemtype = "Action",
                                                   name = (string)pa.Attribute("name"),
                                                   package = (string)pa.Attribute("package"),
                                                   //type_name = (string)pa.Element("type").Attribute("name"),
                                                   //type_package = (string)pa.Element("type").Attribute("package"),
                                                   value = (string)pa.Element("value").Value,
                                                   text = (string)pa.Element("text").Value
                                               }))
                                       }).ToList();

            rows = null;

            //targetinfo.BeginLoadData();
            i = 0;
            while (!bw.CancellationPending)
            {
                if (i == 5)
                    targetinfo.BeginLoadData();

                ProcessEvent(events[i]);
                i++;

                if (i % 50 == 0)
                    bw.ReportProgress((int)((float)i / (float)events.Count * 100));
                //if (i % 1000 == 0)
                //    targetinfo.EndLoadData();
                if (i >= events.Count)
                    break;
            }
            targetinfo.EndLoadData();

            ChangeStatus(LoadStatus.Completed);
        }

        private object[] GetColumnData(FiredEvent fe)
        {
            object[] retval = new string[DataColumns.Count];

            foreach (DataColumn dc in targetinfo.Columns)
                retval[dc.Ordinal] = (fe.EventPayloadItemCollection[dc.ColumnName].Text == string.Empty ? fe.EventPayloadItemCollection[dc.ColumnName].Value : fe.EventPayloadItemCollection[dc.ColumnName].Text);


            return retval;
        }

        private class SyncEvents
        {
            public SyncEvents()
            {
                _producerCompleteEvent = new ManualResetEvent(false);
                _newItemEvent = new AutoResetEvent(false);
                _exitThreadEvent = new ManualResetEvent(false);
                _eventArray = new WaitHandle[2];
                _eventArray[0] = _newItemEvent;
                _eventArray[1] = _exitThreadEvent;
            }

            public EventWaitHandle ProducerCompleteEvent
            {
                get { return _producerCompleteEvent; }
            }
            public EventWaitHandle ExitThreadEvent
            {
                get { return _exitThreadEvent; }
            }
            public EventWaitHandle NewItemEvent
            {
                get { return _newItemEvent; }
            }
            public WaitHandle[] EventArray
            {
                get { return _eventArray; }
            }

            private EventWaitHandle _newItemEvent;
            private EventWaitHandle _exitThreadEvent;
            private EventWaitHandle _producerCompleteEvent;
            private WaitHandle[] _eventArray;
        }

        private DataTable stager;
        Queue<FiredEvent> _queue = new Queue<FiredEvent>();
        SyncEvents _syncEvents = new SyncEvents();
        private object locker = new object();

        private void ConsumeEvents()
        {
            DataTable stager = new DataTable("Staging");
            stager.Columns.Add("Id");
            stager.Columns.Add("Name");
            stager.Columns.Add("Package");
            stager.Columns.Add("Version");
            stager.Columns.Add("TimeStamp");

            foreach (string s in DataColumns)
            {
                stager.Columns.Add(s);
            }
            DataRow row;
            FiredEvent firedevent;
            int count = 0;
            while (WaitHandle.WaitAny(_syncEvents.EventArray) != 1)
            {

                //DateTime startTime = DateTime.Now;
                //DateTime endTime;
                //TimeSpan duration;

                lock (((ICollection)_queue).SyncRoot)
                {
                    firedevent = _queue.Dequeue();
                    System.Diagnostics.Debug.WriteLine(string.Format("Item Dequeued Queue Count={0}", _queue.Count));
                }

                //ThreadPool.QueueUserWorkItem(ProcessEvent, firedevent);

                //endTime = DateTime.Now;
                //duration = endTime - startTime;
                //System.Diagnostics.Debug.WriteLine(string.Format("Duration for Dequeue was {0} ms.", duration.TotalMilliseconds));

                //startTime = DateTime.Now;

                row = stager.Rows.Add();

                //endTime = DateTime.Now;
                //duration = endTime - startTime;
                //System.Diagnostics.Debug.WriteLine(string.Format("Duration for NewRow create was {0} ms.", duration.TotalMilliseconds));

                //startTime = DateTime.Now;

                row["Id"] = firedevent.Id;
                row["Name"] = firedevent.Name;
                row["Package"] = firedevent.Package;
                row["Version"] = firedevent.Version;
                row["TimeStamp"] = firedevent.Timestamp;
                foreach (EventPayloadItem epi in firedevent.EventPayloadItemCollection)
                {
                    if (epi.Text == string.Empty)
                        row[epi.Name] = epi.Value;
                    else
                        row[epi.Name] = epi.Text;
                }

                //endTime = DateTime.Now;
                //duration = endTime - startTime;
                //System.Diagnostics.Debug.WriteLine(string.Format("Duration for Row Population was {0} ms.", duration.TotalMilliseconds));

                //targetinfo.ImportRow(row);
                //startTime = DateTime.Now;

                if (stager.Rows.Count == 100)
                {
                    lock (locker)
                    {
                        foreach (DataRow r in stager.Rows)
                        {
                            targetinfo.LoadDataRow(r.ItemArray, false);
                        }

                        //targetinfo.Merge(stager, true, MissingSchemaAction.Add);
                    }
                    stager.Clear();

                }

                count++;

                //endTime = DateTime.Now;
                //duration = endTime - startTime;
                //System.Diagnostics.Debug.WriteLine(string.Format("Duration for Add tp DataTable was {0} ms.", duration.TotalMilliseconds));
                //bool t = Thread.CurrentThread.IsThreadPoolThread;
            }
            Console.WriteLine("Consumer Thread: consumed {0} items", count);
        }
        public void ProduceEvents()
        {
            // Get File Information 
            string file = Parent.Options["filename"].Value;
            string meta;

            if (Parent.Options.Where(p => p.Name == "metadatafile").Count() > 0)
                meta = Parent.Options["metadatafile"].Value;
            else
                meta = file.Substring(0, file.LastIndexOf(".")) + ".XEM";

            string filename = file.Substring(0, file.LastIndexOf(".")) + "*" + file.Substring(file.LastIndexOf("."));
            string metaname = meta.Substring(0, meta.LastIndexOf(".")) + "*" + meta.Substring(meta.LastIndexOf("."));

            string cmd = string.Format(SqlCommandStrings.FileTargetData, filename, metaname);

            SqlConnection conn = new SqlConnection(Server.ServerConnection.ConnectionString);
            conn.Open();
            SqlCommand sqlcmd = new SqlCommand(cmd, conn);
            SqlDataReader dr = sqlcmd.ExecuteReader();

            fn_xe_file_target_read_file filedata;
            FiredEvent firedevent;

            int count = 0;
            while ((!_syncEvents.ProducerCompleteEvent.WaitOne(0, false)) && (!_syncEvents.ExitThreadEvent.WaitOne(0, false)))
            {
                while (dr.Read())
                {
                    filedata = new fn_xe_file_target_read_file(dr);
                    firedevent = (
                                from fe in filedata.event_data.Elements()
                                select new FiredEvent
                                {
                                    name = (string)fe.Attribute("name"),
                                    package = (string)fe.Attribute("package"),
                                    id = (string)fe.Attribute("id"),
                                    version = (string)fe.Attribute("version"),
                                    timestamp = (string)fe.Attribute("timestamp"),
                                    payloaddata = new EventPayloadItemCollection((
                                        from pc in fe.Descendants("data")
                                        select new EventPayloadItem(Server)
                                        {
                                            payloaditemtype = "Column",
                                            name = (string)pc.Attribute("name"),
                                            package = (string)pc.Attribute("package"),
                                            //type_name = (string)pc.Element("type").Attribute("name"),
                                            //type_package = (string)pc.Element("type").Attribute("package"),
                                            value = (string)pc.Element("value").Value,
                                            text = (string)pc.Element("text").Value
                                        }).Union<EventPayloadItem>(
                                        from pa in fe.Descendants("action")
                                        select new EventPayloadItem(Server)
                                        {
                                            payloaditemtype = "Action",
                                            name = (string)pa.Attribute("name"),
                                            package = (string)pa.Attribute("package"),
                                            //type_name = (string)pa.Element("type").Attribute("name"),
                                            //type_package = (string)pa.Element("type").Attribute("package"),
                                            value = (string)pa.Element("value").Value,
                                            text = (string)pa.Element("text").Value
                                        }))
                                }).ElementAt(0);

                    lock (((ICollection)_queue).SyncRoot)
                    {
                        this.events.Add(firedevent);
                        _queue.Enqueue(firedevent);
                        _syncEvents.NewItemEvent.Set();
                        count++;
                    }

                    if (count % 100 == 0)
                        Thread.Sleep(500);

                }
                _syncEvents.ProducerCompleteEvent.Set();
            }
            Console.WriteLine("Producer thread: produced {0} items", count);

        }
        public void LoadTargetDataAsync()
        {
            string data = Parent.Parent.Server.ServerConnection.ExecuteScalar(string.Format(SqlCommandStrings.TargetData, Parent.parent.Name, Parent.Name.Split('.').ElementAt(1))).ToString();
            XDocument xdocument = XDocument.Parse(data);

            this.truncated = (int)xdocument.Element("FileTarget").Attribute("truncated");
            this.buffersdropped = (int)xdocument.Element("FileTarget").Element("Buffers").Attribute("logged");
            this.bufferslogged = (int)xdocument.Element("FileTarget").Element("Buffers").Attribute("dropped");


            Thread producerThread = new Thread(ProduceEvents);
            producerThread.IsBackground = true;
            producerThread.Priority = ThreadPriority.BelowNormal;

            Thread consumerThread = new Thread(ConsumeEvents);
            consumerThread.IsBackground = true;
            consumerThread.Priority = ThreadPriority.AboveNormal;
            Thread consumerThread2 = new Thread(ConsumeEvents);
            consumerThread2.IsBackground = true;
            consumerThread2.Priority = ThreadPriority.AboveNormal;


            consumerThread.Start();
            consumerThread2.Start();
            producerThread.Start();

            //for (int i=0; i<4; i++)
            //{
            //    Thread.Sleep(2500);
            //    ShowQueueContents(queue);
            //}

            //Console.WriteLine("Signaling threads to terminate...");
            //syncEvents.ExitThreadEvent.Set();

            producerThread.Join();
            consumerThread.Join();
            consumerThread2.Join();

        }

        public void LoadTargetDataOld()
        {
            GetFileList();

            string data = Parent.Parent.Server.ServerConnection.ExecuteScalar(string.Format(SqlCommandStrings.TargetData, Parent.parent.Name, Parent.Name.Split('.').ElementAt(1))).ToString();
            XDocument xdocument = XDocument.Parse(data);

            this.truncated = (int)xdocument.Element("FileTarget").Attribute("truncated");
            this.buffersdropped = (int)xdocument.Element("FileTarget").Element("Buffers").Attribute("logged");
            this.bufferslogged = (int)xdocument.Element("FileTarget").Element("Buffers").Attribute("dropped");

            // Get File Information 
            string file = Parent.Options["filename"].Value;
            string meta;

            if (Parent.Options.Where(p => p.Name == "metadatafile").Count() > 0)
                meta = Parent.Options["metadatafile"].Value;
            else
                meta = file.Substring(0, file.LastIndexOf(".")) + ".XEM";

            string filename = file.Substring(0, file.LastIndexOf(".")) + "*" + file.Substring(file.LastIndexOf("."));
            string metaname = meta.Substring(0, meta.LastIndexOf(".")) + "*" + meta.Substring(meta.LastIndexOf("."));

            string cmd = string.Format(SqlCommandStrings.FileTargetData, filename, metaname);

            SqlConnection conn = new SqlConnection(Server.ServerConnection.ConnectionString);
            conn.Open();
            SqlCommand sqlcmd = new SqlCommand(cmd, conn);
            SqlDataReader dr = sqlcmd.ExecuteReader();

            fn_xe_file_target_read_file filedata;
            XDocument xdoc;
            FiredEvent firedevent;
            DataRow row;

            while (dr.Read())
            {

                //DateTime startTime = DateTime.Now;

                filedata = new fn_xe_file_target_read_file(dr);
                //xdoc = XDocument.Parse(filedata.event_data);
                firedevent = (
                            from fe in filedata.event_data.Elements()
                            select new FiredEvent
                            {
                                name = (string)fe.Attribute("name"),
                                package = (string)fe.Attribute("package"),
                                id = (string)fe.Attribute("id"),
                                version = (string)fe.Attribute("version"),
                                timestamp = (string)fe.Attribute("timestamp"),
                                payloaddata = new EventPayloadItemCollection((
                                    from pc in fe.Descendants("data")
                                    select new EventPayloadItem(Server)
                                    {
                                        payloaditemtype = "Column",
                                        name = (string)pc.Attribute("name"),
                                        package = (string)pc.Attribute("package"),
                                        //type_name = (string)pc.Element("type").Attribute("name"),
                                        //type_package = (string)pc.Element("type").Attribute("package"),
                                        value = (string)pc.Element("value").Value,
                                        text = (string)pc.Element("text").Value
                                    }).Union<EventPayloadItem>(
                                    from pa in fe.Descendants("action")
                                    select new EventPayloadItem(Server)
                                    {
                                        payloaditemtype = "Action",
                                        name = (string)pa.Attribute("name"),
                                        package = (string)pa.Attribute("package"),
                                        //type_name = (string)pa.Element("type").Attribute("name"),
                                        //type_package = (string)pa.Element("type").Attribute("package"),
                                        value = (string)pa.Element("value").Value,
                                        text = (string)pa.Element("text").Value
                                    }))
                            }).ElementAt(0);

                //DateTime evnt = DateTime.Now;
                //TimeSpan intermed = evnt - startTime;
                //System.Diagnostics.Debug.WriteLine(string.Format("      Duration for event was {0} ms.", intermed.TotalMilliseconds));



                row = targetinfo.Rows.Add();

                //DateTime rowcreate1 = DateTime.Now;
                //TimeSpan intermed_row1 = rowcreate1 - evnt;
                //System.Diagnostics.Debug.WriteLine(string.Format("      Duration for Row Creation was {0} ms.", intermed_row1.TotalMilliseconds));

                row["Id"] = firedevent.Id;
                row["Name"] = firedevent.Name;
                row["Package"] = firedevent.Package;
                row["Version"] = firedevent.Version;
                row["TimeStamp"] = firedevent.Timestamp;
                foreach (EventPayloadItem epi in firedevent.EventPayloadItemCollection)
                {
                    if (epi.Text == string.Empty)
                        row[epi.Name] = epi.Value;
                    else
                        row[epi.Name] = epi.Text;
                }

                //DateTime rowcreate = DateTime.Now;
                //TimeSpan intermed_row = rowcreate - rowcreate1;
                //System.Diagnostics.Debug.WriteLine(string.Format("      Duration for Row population was {0} ms.", intermed_row.TotalMilliseconds));


                this.events.Add(firedevent);

                //DateTime endTime = DateTime.Now;
                //TimeSpan addevnt = endTime - rowcreate;
                //System.Diagnostics.Debug.WriteLine(string.Format("       Duration on Add Event was {0} ms.", addevnt.TotalMilliseconds));

                //TimeSpan totalduration = endTime - startTime;
                //System.Diagnostics.Debug.WriteLine(string.Format("Duration on loop was {0} ms.", totalduration.TotalMilliseconds));

            }
            dr.Close();
            conn.Close();
        }


        public void LoadTargetData2()
        {
            GetFileList();

            string data = Parent.Parent.Server.ServerConnection.ExecuteScalar(string.Format(SqlCommandStrings.TargetData, Parent.parent.Name, Parent.Name.Split('.').ElementAt(1))).ToString();
            XDocument xdocument = XDocument.Parse(data);

            this.truncated = (int)xdocument.Element("FileTarget").Attribute("truncated");
            this.buffersdropped = (int)xdocument.Element("FileTarget").Element("Buffers").Attribute("logged");
            this.bufferslogged = (int)xdocument.Element("FileTarget").Element("Buffers").Attribute("dropped");

            // Get File Information 
            string file = Parent.Options["filename"].Value;
            string meta;

            if (Parent.Options.Where(p => p.Name == "metadatafile").Count() > 0)
                meta = Parent.Options["metadatafile"].Value;
            else
                meta = file.Substring(0, file.LastIndexOf(".")) + ".XEM";

            string filename = file.Substring(0, file.LastIndexOf(".")) + "*" + file.Substring(file.LastIndexOf("."));
            string metaname = meta.Substring(0, meta.LastIndexOf(".")) + "*" + meta.Substring(meta.LastIndexOf("."));

            string cmd = string.Format(SqlCommandStrings.FileTargetData, filename, metaname);

            SqlConnection conn = new SqlConnection(Server.ServerConnection.ConnectionString);
            conn.Open();
            SqlCommand sqlcmd = new SqlCommand(cmd, conn);
            SqlDataReader dr = sqlcmd.ExecuteReader();

           // fn_xe_file_target_read_file eventinfo = new fn_xe_file_target_read_file();

            targetinfo.BeginLoadData();

            while (dr.Read())
            {
                ProcessEvent(GetFiredEvent(new fn_xe_file_target_read_file(dr)));
            }

            targetinfo.EndLoadData();
        }


        public new void LoadTargetDataBulk_old()
        {
            GetFileList();

            string data = Parent.Parent.Server.ServerConnection.ExecuteScalar(string.Format(SqlCommandStrings.TargetData, Parent.parent.Name, Parent.Name.Split('.').ElementAt(1))).ToString();
            XDocument xdocument = XDocument.Parse(data);

            this.truncated = (int)xdocument.Element("FileTarget").Attribute("truncated");
            this.buffersdropped = (int)xdocument.Element("FileTarget").Element("Buffers").Attribute("logged");
            this.bufferslogged = (int)xdocument.Element("FileTarget").Element("Buffers").Attribute("dropped");

            // Get File Information 
            string file = Parent.Options["filename"].Value;
            string meta;

            if (Parent.Options.Where(p => p.Name == "metadatafile").Count() > 0)
                meta = Parent.Options["metadatafile"].Value;
            else
                meta = file.Substring(0, file.LastIndexOf(".")) + ".XEM";

            string filename = file.Substring(0, file.LastIndexOf(".")) + "*" + file.Substring(file.LastIndexOf("."));
            string metaname = meta.Substring(0, meta.LastIndexOf(".")) + "*" + meta.Substring(meta.LastIndexOf("."));

            string cmd = string.Format(SqlCommandStrings.FileTargetData, filename, metaname);

            SqlConnection conn = new SqlConnection(Server.ServerConnection.ConnectionString);
            conn.Open();
            SqlCommand sqlcmd = new SqlCommand(cmd, conn);
            SqlDataReader dr = sqlcmd.ExecuteReader();

            DateTime startTime = DateTime.Now;
            DateTime endTime;
            TimeSpan duration;

            List<fn_xe_file_target_read_file> eventinfo = new List<fn_xe_file_target_read_file>();

            while (dr.Read())
            {
                eventinfo.Add(new fn_xe_file_target_read_file(dr));
            }
            dr.Close();
            conn.Close();

            endTime = DateTime.Now;
            duration = endTime - startTime;
            System.Diagnostics.Debug.WriteLine(string.Format("Duration for SqlDataReader was {0} ms.", duration.TotalMilliseconds));

            startTime = DateTime.Now;

            this.events = new FiredEventCollection(
                (from e in eventinfo
                 from fe in e.event_data.Elements()
                 select new FiredEvent
                 {
                     name = (string)fe.Attribute("name"),
                     package = (string)fe.Attribute("package"),
                     id = (string)fe.Attribute("id"),
                     version = (string)fe.Attribute("version"),
                     timestamp = (string)fe.Attribute("timestamp"),
                     payloaddata = new EventPayloadItemCollection((
                         from pc in fe.Descendants("data")
                         select new EventPayloadItem(Server)
                         {
                             payloaditemtype = "Column",
                             name = (string)pc.Attribute("name"),
                             package = (string)pc.Attribute("package"),
                             //type_name = (string)pc.Element("type").Attribute("name"),
                             //type_package = (string)pc.Element("type").Attribute("package"),
                             value = (string)pc.Element("value").Value,
                             text = (string)pc.Element("text").Value
                         }).Union<EventPayloadItem>(
                         from pa in fe.Descendants("action")
                         select new EventPayloadItem(Server)
                         {
                             payloaditemtype = "Action",
                             name = (string)pa.Attribute("name"),
                             package = (string)pa.Attribute("package"),
                             //type_name = (string)pa.Element("type").Attribute("name"),
                             //type_package = (string)pa.Element("type").Attribute("package"),
                             value = (string)pa.Element("value").Value,
                             text = (string)pa.Element("text").Value
                         }))
                 }));

            endTime = DateTime.Now;
            duration = endTime - startTime;
            System.Diagnostics.Debug.WriteLine(string.Format("Duration for EventParsing was {0} ms.", duration.TotalMilliseconds));

            int i = 0;
            foreach (FiredEvent fe in events)
            {
                if (i == 1)
                    targetinfo.BeginLoadData();
                i++;
                ProcessEvent(fe);
                if (i % 1000 == 0)
                {
                    targetinfo.EndLoadData();
                    i = 0;
                }
            }


            //DataRow row = targetinfo.Rows.Add();


            //    row["Id"] = firedevent.Id;
            //    row["Name"] = firedevent.Name;
            //    row["Package"] = firedevent.Package;
            //    row["Version"] = firedevent.Version;
            //    row["TimeStamp"] = firedevent.Timestamp;
            //    foreach (EventPayloadItem epi in firedevent.EventPayloadItemCollection)
            //    {
            //        if (epi.Text == string.Empty)
            //            row[epi.Name] = epi.Value;
            //        else
            //            row[epi.Name] = epi.Text;
            //    }

            //    //DateTime rowcreate = DateTime.Now;
            //    //TimeSpan intermed_row = rowcreate - rowcreate1;
            //    //System.Diagnostics.Debug.WriteLine(string.Format("      Duration for Row population was {0} ms.", intermed_row.TotalMilliseconds));


            //    this.events.Add(firedevent);

            //    //DateTime endTime = DateTime.Now;
            //    //TimeSpan addevnt = endTime - rowcreate;
            //    //System.Diagnostics.Debug.WriteLine(string.Format("       Duration on Add Event was {0} ms.", addevnt.TotalMilliseconds));

            //    //TimeSpan totalduration = endTime - startTime;
            //    //System.Diagnostics.Debug.WriteLine(string.Format("Duration on loop was {0} ms.", totalduration.TotalMilliseconds));
        }

        public System.Data.DataTable GetEventsAsDataTable()
        {

            //(from e in this.Parent.Parent.Events
            // from c in this.Server.MetaData.Events
            // where e.Name == c.Name
            // select c.Columns);

            System.Data.DataTable dt = new System.Data.DataTable("EventInformation");

            dt.Columns.Add("Id");
            dt.Columns.Add("Name");
            dt.Columns.Add("Package");
            dt.Columns.Add("Version");
            dt.Columns.Add("TimeStamp");

            foreach (string s in DataColumns)
            {
                dt.Columns.Add(s);
            }

            foreach (FiredEvent fe in this.Events)
            {
                System.Data.DataRow dr = dt.Rows.Add();
                dr["Id"] = fe.Id;
                dr["Name"] = fe.Name;
                dr["Package"] = fe.Package;
                dr["Version"] = fe.Version;
                dr["TimeStamp"] = fe.Timestamp;
                foreach (EventPayloadItem epi in fe.EventPayloadItemCollection)
                {
                    if (epi.Text == string.Empty)
                    dr[epi.Name] = epi.Value;
                    else
                        dr[epi.Name] = epi.Text;
                }
                //dt.Rows.Add(dr);

            }
            return dt;
        }

        #endregion

    }
}
